package net.wexoo.onlinedivelog.view.pages.detail.dive;

import static org.slf4j.LoggerFactory.getLogger;
import net.wexoo.onlinedivelog.entity.dive.DiveBean;
import net.wexoo.onlinedivelog.entity.diveGuide.DiveGuideBean;
import net.wexoo.onlinedivelog.proxy.dive.IDiveProxy;
import net.wexoo.onlinedivelog.proxy.diveguide.IDiveGuideProxy;
import net.wexoo.onlinedivelog.reusable.SameActionOnClickAjaxButton;
import net.wexoo.onlinedivelog.reusable.behaviour.AjaxCSSClassAppender;
import net.wexoo.onlinedivelog.reusable.model.ApostrophResourceModel;
import net.wexoo.onlinedivelog.reusable.page.WEXWebPage;
import net.wexoo.onlinedivelog.view.util.NotificationPanel;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;

public class DiveDetailPage extends WEXWebPage {

  private static final long serialVersionUID = 1L;

  private NotificationPanel notificationPanel;
  private final Form<DiveBean> diveForm;

  private DiveBean diveBean;

  @SpringBean(name = "diveProxy")
  private IDiveProxy diveProxy;
  @SpringBean
  private IDiveGuideProxy diveGuideProxy;

  public DiveDetailPage(DiveBean diveBean) {

    this.diveBean = diveBean;

    buildNotificationPanel();

    // parent node
    diveForm = new Form<DiveBean>("userForm", new CompoundPropertyModel<DiveBean>(diveBean));
    add(diveForm);

    buildSaveButton();

    buildCancelButton();

    buildDiveDataFields();

    buildDiveGuideChoice();

    diveForm.add(new AjaxFormValidatingBehavior(diveForm, "onLoad"));

    diveForm.visitChildren(FormComponent.class,
        new IVisitor<FormComponent<?>, Void>() {

      @Override
      public void component(FormComponent<?> formComponent, IVisit<Void> visit) {
        formComponent.add(new AjaxCSSClassAppender(notificationPanel));
        visit.dontGoDeeper();
      }
    });
  }

  private void buildNotificationPanel() {
    notificationPanel = new NotificationPanel("divePanelNotificationPanel");
    add(notificationPanel);
  }

  private void buildSaveButton() {
    AjaxButton registerButton = new AjaxButton("saveButton") {

      private static final long serialVersionUID = 1L;

      @Override
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        diveProxy.saveOrUpdate(diveBean);

        String successMessage = getString("diveIn") + " " + diveBean.getDiveSite() + new ResourceModel("successfullySaved");

        info(successMessage);
        getLogger(getClass()).info(successMessage);
        dataChanged = true;
        notificationPanel.refresh(target);
        ModalWindow.closeCurrent(target);
      }

      @Override
      protected void onError(AjaxRequestTarget target, Form<?> form) {
        notificationPanel.refresh(target);
      }
    };
    diveForm.add(registerButton);
  }

  private void buildCancelButton() {
    AjaxButton cancel = new SameActionOnClickAjaxButton("cancelButton") {
      private static final long serialVersionUID = 1L;

      @Override
      protected void doOnClickAction(AjaxRequestTarget target, Form<?> form) {
        ModalWindow.closeCurrent(target);
      }
    };
    diveForm.add(cancel);
  }

  private void buildDiveGuideChoice() {
    DropDownChoice<DiveGuideBean> diveGuideChoice =
        new DropDownChoice<DiveGuideBean>("diveGuideChoice", new PropertyModel<DiveGuideBean>(diveBean, "diveGuide"),
            diveGuideProxy.getAll(), new ChoiceRenderer<DiveGuideBean>("login"));

    setLabelOfComponent(diveGuideChoice, "diveGuideLabel");
    diveGuideChoice.setRequired(true);
    diveForm.add(diveGuideChoice);
  }

  private void buildDiveDataFields() {
    diveForm.add(new RequiredTextField<String>("diveSite").setLabel(new ApostrophResourceModel("diveSiteLabel")));
    diveForm.add(new RequiredTextField<String>("diveDate").setLabel(new ApostrophResourceModel("dateLabel")));
    diveForm.add(new TextField<String>("maxDepth").setLabel(new ApostrophResourceModel("depthLabel")));
  }

  public FormComponent<?> setLabelOfComponent(FormComponent<?> component, String label) {
    component.setLabel(new ApostrophResourceModel(label));
    return component;
  }
}